import { Injectable, NotFoundException } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';

import { PermissionControlEntity } from '../permission-control/permission-control.entity';
import { PermissionEntity } from '../permission/permission.entity';
import { CreateRoleDto } from './dto/create-role.dto';
import { FindRoleDto } from './dto/find-role.dto';
import { UpdateRoleDto } from './dto/update-role.dto';
import { RoleEntity } from './role.entity';

@Injectable()
export class RoleService {
  constructor(
    @InjectRepository(RoleEntity)
    private readonly roleRepo: Repository<RoleEntity>,
    @InjectRepository(PermissionEntity)
    private readonly permissionRepo: Repository<PermissionEntity>,
    @InjectRepository(PermissionControlEntity)
    private readonly permissionControlRepo: Repository<PermissionControlEntity>,
  ) {}

  async create(createRoleDto: CreateRoleDto) {
    const permissions = await this.permissionRepo
      .createQueryBuilder('p')
      .select('p.id')
      .where('p.deletedAt IS NULL')
      .getMany();

    const r = await this.roleRepo.create(createRoleDto);
    const role = await this.roleRepo.save(r);

    for (const { id } of permissions) {
      const pc = this.permissionControlRepo.create({
        permissionId: id,
        roleId: role.id,
      });
      await this.permissionControlRepo.save(pc);
    }
  }

  async delete(id: number) {
    // delete 方法不判断数据库中是否存在，不报错
    const role = await this.roleRepo.findOneById(id);
    if (!role) {
      throw new NotFoundException('未找到该条数据');
    }
    this.roleRepo.updateById(id, { deletedAt: new Date() });
  }

  async update(id: number, updateRoleDto: UpdateRoleDto) {
    const role = await this.roleRepo.findOneById(id);
    if (!role) {
      throw new NotFoundException('未找到该条数据');
    }
    return this.roleRepo.updateById(id, updateRoleDto);
  }

  async findAll(findRoleDto: FindRoleDto) {
    const { name, pn, ps } = findRoleDto;
    const [data, total] = await this.roleRepo
      .createQueryBuilder('role')
      .where('role.roleName LIKE :name', { name: `%${name}%` })
      .andWhere('role.deletedAt IS NULL')
      .orderBy('role.createdAt', 'DESC')
      .skip((pn - 1) * ps)
      .take(ps)
      .getManyAndCount();
    return { data, pn, ps, total };
  }
}
